using System;
using System.Collections;
using System.Web.Mvc;
using System.Web.Routing;
using Boo.Lang;

namespace MvcContrib.Comdiv.Framework{
    public interface IApplicationStartTask{
        int Idx { get; }
        void Execute();
    }

    public interface IRouteStartup : IApplicationStartTask{
        void RegisterRouts(RouteCollection routes);
    }

    [AttributeUsage(AttributeTargets.Class)]
    public sealed class StartupObjectAttribute : Attribute {}

    public abstract class ApplicationStartTaskBase<T> : IApplicationStartTask where T : class, IApplicationStartTask{
        #region IApplicationStartTask Members

        public int Idx { get; set; }
        private bool executed = false;
        public void Execute(){
            if(executed)return;
            executed = true;
            internalExecute();
        }

        protected abstract void internalExecute();

        #endregion

        public T idx(int idx){
            Idx = idx;
            return this as T;
        }
    }

    public class RouteRegister : ApplicationStartTaskBase<RouteRegister>, IRouteStartup{
        public string Name { get; set; }
        public string Url { get; set; }
        public object Defaults { get; set; }
        public object Constraints { get; set; }

        #region IRouteStartup Members
        public RouteRegister(){
            
        }

        public RouteRegister(string url,object defaults){
            this.url(url).defaults(defaults);
        }

        protected override void internalExecute(){
            RegisterRouts(RouteTable.Routes);
        }

        public virtual void RegisterRouts(RouteCollection routes){
            var r = new Route(Url, new MvcRouteHandler());
            r.Defaults = ((RouteData) Defaults).Values;
            routes.Add(r);
        }

        #endregion

        public RouteRegister name(string name){
            Name = name;
            return this;
        }

        public RouteRegister url(string url){
            Url = url;
            return this;
        }

        public RouteRegister defaults(object defaults){
            Defaults = defaults;
            if (defaults is Hash){
//for boo proposes
                var r = new RouteData();
                var hash = (Hashtable) defaults;
                foreach (object key in hash.Keys){
                    r.Values[key.ToString()] = hash[key];
                }
                Defaults = r;
            }
            return this;
        }

        public RouteRegister constraints(object constraints){
            Constraints = constraints;
            return this;
        }
    }
}